using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Xna.Framework;
using System.Runtime.Serialization;
using editor;
using System.Windows.Input;
using System.Windows.Ink;

namespace editor
{
    public enum TypeOfPolygon
    {
        LookAt, Exit, WalkToNearestPoint
    };
}
namespace xml_classes
{
    [DataContract]
    public class ScreenFromEditor
    {
        [DataMember]
        public List<Polygon> _polygons;
        [DataMember]
        public ImageFitToScreen _GameScreen;
        [DataMember]
        public ImageFitToScreen _WalkingMap;
        [DataMember]
        public Vector2 _StartingPoint;
        [DataMember]
        public int _Width;
        [DataMember]
        public int _Height;
        [DataMember]
        public int _Stride;

        public ScreenFromEditor(List<Polygon> polygons, ImageFitToScreen GameScreen, ImageFitToScreen WalkingMap, Vector2 StartingPoint)
        {
            _polygons = polygons;
            _GameScreen = GameScreen;
            _WalkingMap = WalkingMap;
            _StartingPoint = StartingPoint;
        }
        public ScreenFromEditor()
        {

        }
    }

    [DataContract]
    public class ImageFitToScreen
    {
        [DataMember]
        private string _Path;
        [DataMember]
        private string _Purpose;
        [DataMember]
        private double _Width;
        [DataMember]
        private double _Height;

        public string GetPath()
        {
            return _Path;
        }
        public string GetPurpose()
        {
            return _Purpose;
        }
        public double GetWidth()
        {
            return _Width;
        }
        public double GetHeight()
        {
            return _Height;
        }

        #region GameScreen constructors
        public ImageFitToScreen(string Purpose, string Path, double Width, double Height)
        {
            _Path = Path;
            _Width = Width;
            _Purpose = Purpose;
            _Height = Height;

        }
        #endregion

        public void WriteAsXML(System.Xml.XmlTextWriter textWriter)
        {
            textWriter.WriteStartElement(_Purpose);
            textWriter.WriteAttributeString("Path", _Path);
            textWriter.WriteAttributeString("Width", _Width.ToString());
            textWriter.WriteAttributeString("Height", _Height.ToString());
            textWriter.WriteEndElement();
        }
    }

    

    [DataContract]
    public class Polygon
    {
        [DataMember]
        List<Vector2> vertices;

        [DataMember]
        string color;

        [DataMember]
        TypeOfPolygon Type;

        [DataMember]
        Vector2 PositionOfwhereToLookFromAtThePolygon;

        [DataMember]
        string _name;


        #region Polygon constructors

        public Polygon(PolygonStroke Pstroke)
        {
            vertices = new List<Vector2>();
            foreach (System.Windows.Point point in Pstroke.StylusPoints)
            {
                vertices.Add(new Vector2((float)point.X, (float)point.Y));
            }
            color = Pstroke.DrawingAttributes.Color.ToString();
            _name = Pstroke.getName();
            Type = Pstroke.GetType();
            PositionOfwhereToLookFromAtThePolygon = new Vector2((float)Pstroke.GetPositionOfwhereToLookFromAtThePolygon().X, (float)Pstroke.GetPositionOfwhereToLookFromAtThePolygon().Y);

        }

        #endregion


        


        public bool Equals(Polygon pol)
        {
            if (pol.getVertices().Count == vertices.Count && pol.color.Equals(color))
            {
                foreach (Vector2 point1 in pol.getVertices())
                {
                    bool PointFound = false;
                    foreach (Vector2 point2 in vertices)
                    {
                        if (point2.X == point1.X && point2.Y == point1.Y)
                        {
                            PointFound = true;
                            break;
                        }
                    }
                    if (!PointFound)
                    {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }


        #region Polygon getters and setters

        public void SetType(TypeOfPolygon TOP)
        {
            Type = TOP;
        }

        public TypeOfPolygon GetType()
        {
            return Type;
        }

        public void SetPositionOfwhereToLookFromAtThePolygon(float x, float y)
        {
            PositionOfwhereToLookFromAtThePolygon = new Vector2(x,y);
        }

        public Vector2 GetPositionOfwhereToLookFromAtThePolygon()
        {
            return PositionOfwhereToLookFromAtThePolygon;
        }

        public List<Vector2> getVertices()
        {
            return this.vertices; //needs better encapsulation, not really important
        }

        public string getColor()
        {
            return this.color;
        }

        public void setColor(string new_color)
        {
            this.color = new_color;
        }

        #endregion

        #region Polygon functions
        public bool intersects(Polygon other)
        {
            throw new NotImplementedException();
        }

        //return true if point is contained in the polygon
        public bool contains(Vector2 point)
        {
            int polySides = vertices.Count;
            int i = 0, j = polySides - 1;
            bool oddNodes = false;
            for (i = 0; i < polySides; i++)
            {
                if (vertices.ElementAt<Vector2>(i).Y < point.Y && vertices.ElementAt<Vector2>(j).Y >= point.Y
                    || vertices.ElementAt<Vector2>(j).Y < point.Y && vertices.ElementAt<Vector2>(i).Y >= point.Y)
                {
                    if (vertices.ElementAt<Vector2>(i).X + (point.Y - vertices.ElementAt<Vector2>(i).Y) / (vertices.ElementAt<Vector2>(j).Y - vertices.ElementAt<Vector2>(i).Y)
                        * (vertices.ElementAt<Vector2>(j).X - vertices.ElementAt<Vector2>(i).X) < point.X)
                    {

                        oddNodes = !oddNodes;
                    }
                }
                j = i;
            }
            return oddNodes;
        }

        //retrunrs a rectangle bounding the polygon
        public Rectangle getBoundingRectangle()
        {
            bool first = true;
            Rectangle rec = new Rectangle();
            float maxX = 0, maxY = 0, minX = 0, minY = 0;
            foreach (Vector2 vec in this.vertices)
            {
                if (first)
                {
                    maxX = minX = vec.X;
                    maxY = minY = vec.Y;
                    first = false;
                    continue;
                }
                if (vec.X > maxX)
                {
                    maxX = vec.X;
                }
                if (vec.Y > maxY)
                {
                    maxX = vec.X;
                }
                if (vec.X > maxX)
                {
                    maxX = vec.X;
                }
                if (vec.X > maxX)
                {
                    maxX = vec.X;
                }

            }
            return rec;
        }
        #endregion

        #region Polygon Auxiliary functions

        #endregion

        public string getName()
        {
            return _name;
        }
        
        public void setName(string name)
        {
             _name = name;
        }
    }
}